package org.csu.tank.components;

import com.almasb.fxgl.core.math.Vec2;
import com.almasb.fxgl.core.util.LazyValue;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.dsl.components.EffectComponent;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.entity.EntityGroup;
import com.almasb.fxgl.entity.SpawnData;
import com.almasb.fxgl.entity.component.Component;
import com.almasb.fxgl.entity.components.BoundingBoxComponent;
import com.almasb.fxgl.time.LocalTimer;
import org.csu.tank.GameConfig;
import org.csu.tank.effects.ShipEffect;

import java.util.List;

import static com.almasb.fxgl.dsl.FXGL.spawn;
import static org.csu.tank.GameType.*;

/**
 * 玩家的行为,移动和射击
 */
public class PlayerComponent extends Component {
      /**
       * 为了防止出现斜向上,斜向下等角度的移动,
       */
      private boolean movedThisFrame = false;
      private double speed = 0;
      private Vec2 velocity = new Vec2();
      private BoundingBoxComponent bbox;

      private LazyValue<EntityGroup> blocksAll = new LazyValue<>(() -> entity.getWorld().getGroup(BRICK, FLAG, SEA, STONE, ENEMY, BORDER_WALL));
      private LazyValue<EntityGroup> blocks = new LazyValue<>(() -> entity.getWorld().getGroup(BRICK, FLAG, STONE, ENEMY, BORDER_WALL));
      private LocalTimer shootTimer = FXGL.newLocalTimer();

      /**
       * 坦克玩家信息
       **/
      private int id;

      private String name;

      private boolean good;
      private Dir moveDir = Dir.UP;

      public PlayerComponent() {
      }

      @Override
      public void onUpdate(double tpf) {
            speed = tpf * GameConfig.PLAYER_SPEED;
            movedThisFrame = false;
      }

      public void right() {
            if (movedThisFrame) {
                  return;
            }
            movedThisFrame = true;
            getEntity().setRotation(90);
            moveDir = Dir.RIGHT;
            move();
      }

      public void left() {
            if (movedThisFrame) {
                  return;
            }
            movedThisFrame = true;
            getEntity().setRotation(270);
            moveDir = Dir.LEFT;
            move();
      }

      public void down() {
            if (movedThisFrame) {
                  return;
            }
            movedThisFrame = true;
            getEntity().setRotation(180);
            moveDir = Dir.DOWN;
            move();
      }

      public void up() {
            if (movedThisFrame) {
                  return;
            }
            movedThisFrame = true;
            getEntity().setRotation(0);
            moveDir = Dir.UP;
            move();
      }

      private void move() {
            if (!getEntity().isActive()) {//检测实体是否存在
                  return;
            }
            velocity.set((float) (moveDir.getVector().getX() * speed), (float) (moveDir.getVector().getY() * speed));
            int length = Math.round(velocity.length());
            velocity.normalizeLocal();
            List<Entity> blockList;
            if (entity.getComponent(EffectComponent.class).hasEffect(ShipEffect.class)) {
                  blockList = blocks.get().getEntitiesCopy();
            } else {
                  blockList = blocksAll.get().getEntitiesCopy();
            }
            for (int i = 0; i < length; i++) {
                  entity.translate(velocity.x, velocity.y);
                  boolean collision = false;
                  for (int j = 0; j < blockList.size(); j++) {
                        if (blockList.get(j).getBoundingBoxComponent().isCollidingWith(bbox)) {
                              collision = true;
                              break;
                        }
                  }
                  //运动, 遇到障碍物回退
                  if (collision) {
                        entity.translate(-velocity.x, -velocity.y);
                        break;
                  }
            }
      }

      public void moveLocal(double x,double y){
            if (!getEntity().isActive()) {//检测实体是否存在
                  return;
            }
            entity.translate(x-getX(),y-getY());
      }

      public boolean shoot() {
            if (!shootTimer.elapsed(GameConfig.PLAYER_SHOOT_DELAY)) {
                  return false;
            }
            spawn("bullet", new SpawnData(getEntity().getCenter().add(-4, -4.5))
                    .put("direction", moveDir.getVector())
                    .put("owner", entity)
                    .put("ownerId",id));
            shootTimer.capture();
            return true;
      }

//      //子弹追踪
//      public void track() {
//
//            double angle;
//            double π = 3.1415926;
//
//            double Player_X = player.getX();
//            double Player_Y = player.getY();
//            double Bullet_X = bullet.getX();
//            double Bullet_Y = bullet.getY();
//
//            double deltax = Player_X - Bullet_X; // 注意，、是以主角位置为起点 在上图中表示就是x1-x0
//            double deltay = Player_Y - Bullet_Y;
//
//            if (deltax == 0) {
//                  if (Player_Y >= Bullet_Y)             // 子弹需要下移
//                        deltax = 0.0000001;
//                  else                                 // 子弹需要上移
//                        deltax = -0.0000001;
//            }
//
//            if (deltay == 0) {
//                  if (Player_X >= Bullet_X)             // 子弹需要右移
//                        deltay = 0.0000001;
//                  else                                 // 子弹需要左移
//                        deltay = -0.0000001;
//            }
//
//            if (deltax > 0 && deltay > 0)
//                  angle = atan(abs(deltay / deltax));           // 第一项限
//
//            else if (deltax < 0 && deltay < 0)
//                  angle = π - atan(abs(deltay / deltax));         // 第二项限
//
//            else if (deltax < 0 && deltay < 0)
//                  angle = π + atan(abs(deltay / deltax));      // 第三项限
//
//            else
//                  angle = 2 * π - atan(abs(deltay / deltax));      // 第四项限
//
//            Bullet_X += GameConfig.ENEMY_BULLET_SPEED * cos(angle);
//            Bullet_Y += GameConfig.ENEMY_BULLET_SPEED * sin(angle);
//
//            bullet.setX(Bullet_X);
//            bullet.setY(Bullet_Y);
//
//      }

      public boolean shootByEnemy() {
            if (!shootTimer.elapsed(GameConfig.PLAYER_SHOOT_DELAY)) {
                  return false;
            }
            spawn("bulletEnemy", new SpawnData(getEntity().getCenter().add(-4, -4.5))
                    .put("direction", moveDir.getVector())
                    .put("owner", entity)
                    .put("ownerId",id));
            shootTimer.capture();
            return true;
      }


      public Dir getMoveDir() {
            return moveDir;
      }

      public int getId() {
            return id;
      }

      public void setId(int id) {
            this.id = id;
      }

      public String getName() {
            return name;
      }

      public void setName(String name) {
            this.name = name;
      }

      public boolean isGood() {
            return good;
      }

      public void setGood(boolean good) {
            this.good = good;
      }

      public void setMoveDir(Dir moveDir) {
            this.moveDir = moveDir;
            switch (moveDir) {
                  case UP:
                        getEntity().setRotation(0);
                        break;
                  case DOWN:
                        getEntity().setRotation(180);
                        break;
                  case LEFT:
                        getEntity().setRotation(270);
                        break;
                  case RIGHT:
                        getEntity().setRotation(90);
            }
      }

      public double getX() {
            return getEntity().getX();
      }

      public double getY() {
            return getEntity().getY();
      }

}
